#include "snowboy/snowboy-detect-c-wrapper.h"
#include <stdlib.h>
#include <stdio.h>

#include <time.h>
#include <unistd.h> // 用于 sleep 函数

#include "record.h"

#define TIME_THRESHOLD 5 // 5秒

int main()
{
    snd_pcm_uframes_t period; // 周期大小
    snd_pcm_t *capture;       // 音频采集设备
    char *buffer = NULL;      // 存放音频数据的缓冲区
    FILE *fp = NULL;          // 录音文件

    time_t statusTimestamp = 0;
    int statusIsMinusTwo = 0;

    // 创建snowboy检测器
    SnowboyDetect *detector = SnowboyDetectConstructor("common.res", "model.pmdl");
    if (!detector)
    {
        return EXIT_FAILURE;
    }

    SnowboyDetectSetSensitivity(detector, "0.6");
    // SnowboyDetectSetAudioGain(detector, 1.0);

    // 获取检测器支持的音频数据参数
    // 采样深度
    int bits = SnowboyDetectBitsPerSample(detector);
    // 声道数量
    int channels = SnowboyDetectNumChannels(detector);
    // 采样频率
    int rate = SnowboyDetectSampleRate(detector);

    printf("采样深度: %d\n", bits);
    printf("声道数量: %d\n", channels);
    printf("采样频率: %d\n", rate);

    // 打开音频采集设备
    period = 999;
    capture = record_open("default", SND_PCM_FORMAT_S16_LE, channels, rate, &period);
    if (!capture)
    {
        return EXIT_FAILURE;
    }

    buffer = malloc(snd_pcm_frames_to_bytes(capture, period)); // 分配缓冲区
    if (!buffer)
    {
        perror("malloc");
        record_close(capture);
        SnowboyDetectDestructor(detector);
        return EXIT_FAILURE;
    }

    fp = fopen("output.pcm", "wb");
    if (!fp)
    {
        perror("Error opening output file");
        free(buffer);          // 释放缓冲区
        record_close(capture); // 关闭PCM设备
        return EXIT_FAILURE;
    }

    while (1)
    {
        snd_pcm_sframes_t frames = snd_pcm_readi(capture, buffer, period); // 从PCM设备读取数据
        if (frames < 0)
        {
            fprintf(stderr, "Error from read: %s\n", snd_strerror(frames));
            snd_pcm_recover(capture, frames, 0);
        }

        //-2: 表示静音
        //-1: 检测出错
        // 0: 有声音，但不是唤醒词
        //>0: 检测到唤醒词
        int status = SnowboyDetectRunDetection(detector, (int16_t *)buffer, snd_pcm_frames_to_bytes(capture, frames) / sizeof(int16_t), 0);
        printf("%d\n", status);

        if (status > 0)
        {
            printf("检测到唤醒词\n");
            while (1)
            {
                snd_pcm_sframes_t frames = snd_pcm_readi(capture, buffer, period); // 从PCM设备读取数据
                if (frames < 0)
                {
                    fprintf(stderr, "Error from read: %s\n", snd_strerror(frames));
                    snd_pcm_recover(capture, frames, 0);
                }
                fwrite(buffer, snd_pcm_frames_to_bytes(capture, frames), 1, fp); // 将读取的数据写入文件
                status = SnowboyDetectRunDetection(detector, (int16_t *)buffer, snd_pcm_frames_to_bytes(capture, frames) / sizeof(int16_t), 0);
                if (status == -2)
                {
                    if (!statusIsMinusTwo)
                    {
                        statusIsMinusTwo = 1;
                        statusTimestamp = time(NULL); // 记录当前时间
                    }
                }
                else
                {
                    statusIsMinusTwo = 0; // 重置标记
                    statusTimestamp = 0;  // 重置时间戳
                }

                if (statusIsMinusTwo)
                {
                    time_t currentTime = time(NULL);                          // 获取当前时间
                    double timeDiff = difftime(currentTime, statusTimestamp); // 计算时间差
                    if (timeDiff > TIME_THRESHOLD)
                    {
                        printf("Status has been -2 for more than %d seconds.\n", TIME_THRESHOLD);
                        record_close(capture);
                        capture = NULL;
                        break;
                    }
                    else
                    {
                        printf("Status has been -2 for %.2f seconds.\n", timeDiff);
                    }
                }
            }
            break;
        }
    }
    free(buffer); // 释放分配的缓冲区

    SnowboyDetectDestructor(detector);

    return EXIT_SUCCESS;
}